package cn.tedu.springai.controller;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import io.reactivex.Flowable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/ai")
public class SpringAiController {
    @Autowired
    private Generation generation;
    @Value("${ai.api.key}")
    private String appKey;
    @PostMapping("/send")
    /*
     * Flux<ServerSentEvent<String>>是一个非阻塞的、异步的数据流，其中每个元素都是一个ServerSentEvent对象，
     * 其数据字段是一个字符串。这种类型常用于实现服务器端事件流，比如下面向前端实时推送消息的场景。
     */
    public Flux<ServerSentEvent<String>> aiTalk(@RequestBody String question, HttpServletResponse response) throws Exception {
        response.setCharacterEncoding("utf-8");
        // 构建消息对象
        Message message = Message.builder().role(Role.USER.getValue()).content(question).build();
        // 构建通义千问参数对象
        GenerationParam param = GenerationParam.builder()
                .model(Generation.Models.QWEN_PLUS)  //这个模型是阿里云提供的一种人工智能语言模型，用于处理自然语言处理相关的任务
                .messages(Arrays.asList(message))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .topP(0.8)  //这是一个采样策略参数，常用于文本生成模型中
                .apiKey(appKey)
                .build();
        Map<String,String> map1 = new HashMap<>();
        map1.put("text", "");
        // 执行文本生成操作，并流式返回结果
        Flowable<GenerationResult> result = generation.streamCall(param); //流式调用允许客户端以流的方式接收模型生成的响应,实现数据的实时输出，增加用户体验感
        return Flux.from(result)
                .map(m -> {
//                    ServerSentEvent<String> build = ServerSentEvent.<String>builder().data(m.getOutput().getChoices().get(0).getMessage().getContent()).build();

                    String build =ServerSentEvent.<String>builder().data(m.getOutput().getChoices().get(0).getMessage().getContent()).build().data();
                    String text = map1.get("text");
                    map1.put("text" , build);
                    String text1 = build.substring(text.length());
                    System.out.print(text1);
                    return ServerSentEvent.<String>builder().data(build).build();
                });
    }
}
